#region COPYRIGHT
//--------------------------------------------------------------------------------
// <copyright file="Displace.cs" company="starLiGHT Entertainment Studios">
//    Copyright (c) 2007, 2008, 2009, 2010, 2011
//       Roland Rosenkranz (Glatzemann@email.de)
//
//    Based on libnoise by Jason Bevins
//      Copyright (C) 2003, 2004 Jason Bevins (licensed under LGPL)
// </copyright>
// <license>
//   This file is part of starLiGHT.Noise.
//
//   starLiGHT.Noise is free software: you can redistribute it and/or modify
//   it under the terms of the GNU Lesser General Public License as published by
//   the Free Software Foundation, either version 3 of the License, or
//   (at your option) any later version.
//
//   starLiGHT.Noise is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   GNU Lesser General Public License for more details.
//
//   You should have received a copy of the GNU Lesser General Public License
//   along with starLiGHT.Noise. If not, see http://www.gnu.org/licenses/.
//    
//   ADDITIONAL (commercial) LICENSES for starLiGHT.Noise are available on request.
// </license>
// <version>
// **************[ starLiGHT.Engine SVN ]**********************
// * $Rev:: 10385                 $:  Revision of last commit *
// * $Author:: unknown            $:  Author of last commit   *
// * $Date:: 2011-06-14 07:59:17 #$:  Date of last commit     *
// ************************************************************
// </version>
//--------------------------------------------------------------------------------
#endregion

namespace starLiGHT.Noise.Noise
{
    #region Using Statements
    using System;
    using System.Collections.Generic;
    using System.Text;

    #endregion

    /// Noise module that uses three source modules to displace each
    /// coordinate of the input value before returning the output value from
    /// a source module.
    ///
    /// @image html moduledisplace.png
    ///
    /// Unlike most other noise modules, the index value assigned to a source
    /// module determines its role in the displacement operation:
    /// - Source module 0 (left in the diagram) outputs a value.
    /// - Source module 1 (lower left in the diagram) specifies the offset to
    ///   apply to the @a x coordinate of the input value.
    /// - Source module 2 (lower center in the diagram) specifies the
    ///   offset to apply to the @a y coordinate of the input value.
    /// - Source module 3 (lower right in the diagram) specifies the offset
    ///   to apply to the @a z coordinate of the input value.
    ///
    /// The GetValue() method modifies the (@a x, @a y, @a z) coordinates of
    /// the input value using the output values from the three displacement
    /// modules before retrieving the output value from the source module.
    ///
    /// The noise::module::Turbulence noise module is a special case of the
    /// displacement module; internally, there are three Perlin-noise modules
    /// that perform the displacement operation.
    ///
    /// This noise module requires four source modules.
    public class Displace : Module
    {
      /// Constructor.
      public Displace() : base(4)
      {
      }

      /// Returns the @a x displacement module.
      ///
      /// @returns A reference to the @a x displacement module.
      ///
      /// @pre This displacement module has been added to this noise module
      /// via a call to SetSourceModule() or SetXDisplaceModule().
      ///
      /// @throw noise::ExceptionNoModule See the preconditions for more
      /// information.
      ///
      /// The GetValue() method displaces the input value by adding the output
      /// value from this displacement module to the @a x coordinate of the
      /// input value before returning the output value from the source
      /// module.
      public Module GetXDisplaceModule()
      {
        if (sourceModule == null || sourceModule[1] == null)
        {
          throw new Exception("no module");
        }
        return sourceModule[1];
      }

      /// Returns the @a y displacement module.
      ///
      /// @returns A reference to the @a y displacement module.
      ///
      /// @pre This displacement module has been added to this noise module
      /// via a call to SetSourceModule() or SetYDisplaceModule().
      ///
      /// @throw noise::ExceptionNoModule See the preconditions for more
      /// information.
      ///
      /// The GetValue() method displaces the input value by adding the output
      /// value from this displacement module to the @a y coordinate of the
      /// input value before returning the output value from the source
      /// module.
      public Module GetYDisplaceModule()
      {
        if (sourceModule == null || sourceModule[2] == null)
        {
          throw new Exception("no module");
        }
        return sourceModule[2];
      }

      /// Returns the @a z displacement module.
      ///
      /// @returns A reference to the @a z displacement module.
      ///
      /// @pre This displacement module has been added to this noise module
      /// via a call to SetSourceModule() or SetZDisplaceModule().
      ///
      /// @throw noise::ExceptionNoModule See the preconditions for more
      /// information.
      ///
      /// The GetValue() method displaces the input value by adding the output
      /// value from this displacement module to the @a z coordinate of the
      /// input value before returning the output value from the source
      /// module.
      public Module GetZDisplaceModule()
      {
        if (sourceModule == null || sourceModule[3] == null)
        {
          throw new Exception("no module");
        }
        return sourceModule[3];
      }

      /// Sets the @a x, @a y, and @a z displacement modules.
      ///
      /// @param xDisplaceModule Displacement module that displaces the @a x
      /// coordinate of the input value.
      /// @param yDisplaceModule Displacement module that displaces the @a y
      /// coordinate of the input value.
      /// @param zDisplaceModule Displacement module that displaces the @a z
      /// coordinate of the input value.
      ///
      /// The GetValue() method displaces the input value by adding the output
      /// value from each of the displacement modules to the corresponding
      /// coordinates of the input value before returning the output value
      /// from the source module.
      ///
      /// This method assigns an index value of 1 to the @a x displacement
      /// module, an index value of 2 to the @a y displacement module, and an
      /// index value of 3 to the @a z displacement module.
      ///
      /// These displacement modules must exist throughout the lifetime of
      /// this noise module unless another displacement module replaces it.
      public void SetDisplaceModules(Module displaceModuleX, Module displaceModuleY, Module displaceModuleZ)
      {
          this.SetXDisplaceModule(displaceModuleX);
          this.SetYDisplaceModule(displaceModuleY);
          this.SetZDisplaceModule(displaceModuleZ);
      }

      /// Sets the @a x displacement module.
      ///
      /// @param xDisplaceModule Displacement module that displaces the @a x
      /// coordinate.
      ///
      /// The GetValue() method displaces the input value by adding the output
      /// value from this displacement module to the @a x coordinate of the
      /// input value before returning the output value from the source
      /// module.
      ///
      /// This method assigns an index value of 1 to the @a x displacement
      /// module.  Passing this displacement module to this method produces
      /// the same results as passing this displacement module to the
      /// SetSourceModule() method while assigning it an index value of 1.
      ///
      /// This displacement module must exist throughout the lifetime of this
      /// noise module unless another displacement module replaces it.
      public void SetXDisplaceModule(Module displaceModuleX)
      {
          ////assert (pSourceModule != NULL);
            sourceModule[1] = displaceModuleX;
      }

      /// Sets the @a y displacement module.
      ///
      /// @param yDisplaceModule Displacement module that displaces the @a y
      /// coordinate.
      ///
      /// The GetValue() method displaces the input value by adding the output
      /// value from this displacement module to the @a y coordinate of the
      /// input value before returning the output value from the source
      /// module.
      ///
      /// This method assigns an index value of 2 to the @a y displacement
      /// module.  Passing this displacement module to this method produces
      /// the same results as passing this displacement module to the
      /// SetSourceModule() method while assigning it an index value of 2.
      ///
      /// This displacement module must exist throughout the lifetime of this
      /// noise module unless another displacement module replaces it.
      public void SetYDisplaceModule(Module yDisplaceModule)
      {
          ////assert (pSourceModule != NULL);
        sourceModule[2] = yDisplaceModule;
      }

      /// Sets the @a z displacement module.
      ///
      /// @param zDisplaceModule Displacement module that displaces the @a z
      /// coordinate.
      ///
      /// The GetValue() method displaces the input value by adding the output
      /// value from this displacement module to the @a z coordinate of the
      /// input value before returning the output value from the source
      /// module.
      ///
      /// This method assigns an index value of 3 to the @a z displacement
      /// module.  Passing this displacement module to this method produces
      /// the same results as passing this displacement module to the
      /// SetSourceModule() method while assigning it an index value of 3.
      ///
      /// This displacement module must exist throughout the lifetime of this
      /// noise module unless another displacement module replaces it.
      public void SetZDisplaceModule(Module displaceModuleZ)
      {
          ////assert (pSourceModule != NULL);
            sourceModule[3] = displaceModuleZ;
      }

    }
}

